<!DOCTYPE html>
<html>
<head>
<title>InputEvent: beforeinput inputType</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
</head>
<body>
<input type="text" id="input">
<textarea id="textarea"></textarea>
<p id="editable" contenteditable></p>
<script>
test(function() {
    assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.');

    var lastBeforeInputType = '';
    var lastInputType = '';
    const editable = document.getElementById('editable');
    document.addEventListener('beforeinput', function(event) {
        assert_true(event instanceof InputEvent);
        assert_false(event.isComposing);
        lastBeforeInputType = event.inputType;
    });
    document.addEventListener('input', function(event) {
        assert_true(event instanceof InputEvent);
        assert_false(event.isComposing);
        lastInputType = event.inputType;
    });

    const NO_INPUT_EVENT_FIRED = 'NO_INPUT_EVENT_FIRED';
    function testKeyDownInputType(key, modifiers, beforeInputType, inputType) {
        inputType = inputType || beforeInputType;
        lastBeforeInputType = NO_INPUT_EVENT_FIRED;
        lastInputType = NO_INPUT_EVENT_FIRED;
        eventSender.keyDown(key, modifiers);
        assert_equals(lastBeforeInputType, beforeInputType, `${modifiers.toString()}+${key} should produce beforeInputType: ${inputType}`);
        assert_equals(lastInputType, inputType, `${modifiers.toString()}+${key} should produce inputType: ${inputType}`);
    }

    editable.focus();
    // Typing
    testKeyDownInputType('a', [], 'insertText');
    testKeyDownInputType('6', [], 'insertText');
    testKeyDownInputType('l', ['shiftKey'], 'insertText');
    testKeyDownInputType('w', ['shiftKey'], 'insertText');

    // Enter key has different behavior on <input>, <textarea> and ContentEditable.
    document.getElementById('input').focus();
    testKeyDownInputType('Enter', [], 'insertLineBreak', NO_INPUT_EVENT_FIRED);
    testKeyDownInputType('Enter', ['shiftKey'], 'insertLineBreak', NO_INPUT_EVENT_FIRED);

    document.getElementById('textarea').focus();
    testKeyDownInputType('Enter', [], 'insertLineBreak', 'insertLineBreak');
    testKeyDownInputType('Enter', ['shiftKey'], 'insertLineBreak', 'insertLineBreak');

    editable.focus();
    testKeyDownInputType('Enter', [], 'insertParagraph', 'insertParagraph');
    testKeyDownInputType('Enter', ['shiftKey'], 'insertLineBreak', 'insertLineBreak');

    // Deletion
    const isMacOS = navigator.platform.indexOf('Mac') == 0;
    const DELETE_WORD_MODIFIER = isMacOS ? 'altKey' : 'ctrlKey';
    editable.innerHTML = 'abc def</br>123 456';
    const selection = window.getSelection();
    selection.collapse(editable, 1); // End of first line.
    testKeyDownInputType('Backspace', [], 'deleteContentBackward');
    testKeyDownInputType('Delete', [], 'deleteContentForward');
    testKeyDownInputType('Backspace', [DELETE_WORD_MODIFIER], 'deleteWordBackward');
    testKeyDownInputType('Delete', [DELETE_WORD_MODIFIER], 'deleteWordForward');
    // Select and Delete (act as Kill on Mac)
    editable.innerHTML = 'abc def';
    selection.collapse(editable, 0);
    selection.extend(editable, 1);
    testKeyDownInputType('Backspace', [DELETE_WORD_MODIFIER], 'deleteWordBackward');

    // Keyboard commands
    if (!isMacOS) {
        // MacOS's eventSender does not work on hot keys other than arrows.
        testKeyDownInputType('z', ['ctrlKey'], 'historyUndo');
        testKeyDownInputType('z', ['ctrlKey', 'shiftKey'], 'historyRedo');
    }
    // Move command should not generate input events.
    testKeyDownInputType('ArrowLeft', [], NO_INPUT_EVENT_FIRED);
    testKeyDownInputType('ArrowLeft', ['shiftKey'], NO_INPUT_EVENT_FIRED);
    testKeyDownInputType('Home', [], NO_INPUT_EVENT_FIRED);

    // Clipboard
    editable.innerHTML = 'abc';
    selection.collapse(editable, 0);
    selection.extend(editable, 1);
    testKeyDownInputType('Delete', ['shiftKey'], 'deleteByCut');
    testKeyDownInputType('Insert', ['shiftKey'], 'insertFromPaste');
    if (!isMacOS) {
      testKeyDownInputType('v', ['ctrlKey', 'shiftKey'], 'insertFromPaste');
      selection.collapse(editable, 0);
      selection.extend(editable, 1);
      testKeyDownInputType('x', ['ctrlKey'], 'deleteByCut');
      testKeyDownInputType('v', ['ctrlKey'], 'insertFromPaste');
    }
}, 'Testing beforeinput inputType');
</script>
</body>
</html>
